<template>
	<view @tap="reset" class="message-list" :style="{'--theme-color': themeColor}">
		<uni-load-more :status="status" :contentText="{contentnomore: ' '}" />
		<view @tap.stop.prevent="reset(false)" class="message-item" v-for="item in messageList" :key="item.id" :id="'message-'+item.id">
			<xbc-message @imageLoad="onImageLoad" :message="item" :config="config" />
		</view>
		<xbc-message-queue v-if="showQueue" :queue="queue" :config="config" />
		<view class="xbc-editor-placeholder" :style="{height: placeholderHeight}"></view>
	</view>
	<xbc-editor
		@change="editorChange"
		@send="sendMessage"
		@fail="sendMessageFail"
		@toAgent="getConversationDetail"
		@overAgent="getConversationDetail"
		@cancelQueue="getConversationDetail"
		ref="editorRef"
		:conversation="conversation"
		:style="{'--theme-color': themeColor}" />
	<!--评价-->
	<xbc-comment ref="commentRef" :conversation="conversation" :style="{'--theme-color': themeColor}" />
</template>

<script setup>
import { useEditor } from '@/hooks/useEditor'
import { ref, reactive, nextTick, computed, watch } from 'vue'
import { onLoad, onUnload, onPageScroll } from '@dcloudio/uni-app'
import XbcComment from '@/components/xbc-editor/components/more/comment.vue'
import XBCCS from 'xbccs'

const state = reactive({
	conversationId: '',
	nextMessageId: ''
})
const config = ref({})
const user = ref({})
const queue = reactive({})
const status = ref('more')
const editorRef = ref(null)
const commentRef = ref(null)
const messageList = ref([])
const isFirstPage = ref(true)
const themeColor = ref('#409EFF')  // 主题色
const currentScrollTop = ref(0)
const placeholderHeight = ref('92px')
const conversation = ref({})
const { scrollToBottom } = useEditor()
const showQueue = computed(() => {
	return config.value?.isQueue && conversation.value?.status == XBCCS.CONVERSATION_STATUS.QUEUEING
})

// 图片加载完毕
function onImageLoad() {
  if (isFirstPage.value) {
    scrollToBottom()
  }
}

// 消息发送成功
function sendMessage(message){
	messageList.value.push(message)
	scrollToBottom()
}

// 消息发送失败
function sendMessageFail(message){
	if (message.conversationId == state.conversationId) {
		// 更新消息状态
		message.status = XBCCS.MESSAGE_STATUS.FAILED
		
		// 获取当前消息在列表的索引
		const index = messageList.value.findIndex(item => item.id == message.id)
		if(index >= 0){
			messageList.value.splice(index, 1, message)
		}
	}
}

// 编辑器变化
function editorChange(height) {
	placeholderHeight.value = height
}

// 重置状态
function reset(isBottom = true) {
	editorRef.value?.reset(isBottom)
}

// 监听会话已读
function listenConversationRead() {
	messageList.value.forEach((item) => {
		item.isRead = 1
	})
}

// 监听消息已读
function listenMessageRead(res) {
	const readMessageIds = res.list?.map(item => item.id)
	messageList.value.forEach(item => {
		if (readMessageIds.includes(item.id)) {
			item.isRead = 1
		}
	})
}

// 获取配置
async function getConfig() {
	config.value = await XBCCS.getConfig()
	themeColor.value = config.value?.themeColor || '#409EFF'
}

// 获取会话详情
async function getConversationDetail() {
	conversation.value = await XBCCS.getConversationDetail(state.conversationId)
	// 如果是排队状态，获取排队数据
	if (conversation.value?.status === XBCCS.CONVERSATION_STATUS.QUEUEING) {
		getQueueDetail()
	}
}

// 标记历史消息
function markHistoryMesaage() {
	const length = messageList.value.length
	if(!length) return

	const now = new Date().getTime()
	const interval = (config.value?.historyMessageInterval || 60) * 60 * 1000 // 默认1小时
	for(let i = length-1; i >= 0; i--){
		const createTime = messageList.value[i]?.createTime?.replace(/-/g, '/')
		if((now - new Date(createTime).getTime()) >= interval){
			if(messageList.value[i]){
				messageList.value[i].showHistory = true
			}
			break
		}
	}
}

// 获取列表
async function getList() {
	try {
		const { list, nextMessageId } = await XBCCS.getMessageList(state)
		
		// 1. 获取当前第一个元素的ID和位置
		const firstId = messageList.value[0]?.id
		
		// 赋值
		if (state.nextMessageId) {
			isFirstPage.value = false
			messageList.value.unshift(...list)
			await nextTick()
			if (firstId) {
				// 定位当前位置
				const query = uni.createSelectorQuery().in(this)
				query.select('#message-'+firstId).boundingClientRect(({ top })=>{
					uni.pageScrollTo({
						duration: 0,
						scrollTop: top
					})
				}).exec()
			}
		} else {
			messageList.value = list
			await nextTick()
			scrollToBottom()
			
			// 存在未读消息时，并且开启未读已读时
			if(config.value?.isSetRead){
				const hasUnread = list.find(item => item.senderType != 1 && item.isRead == 0)
				hasUnread && XBCCS.setConversationRead(state.conversationId)
			}
		}
		
		// 标记历史消息
		if(config.value?.isHistoryMessage){
			markHistoryMesaage()
		}
		
		state.nextMessageId = nextMessageId
		status.value = nextMessageId ? 'more' : 'no-more'
	} catch (error) {
		console.log(error)
	}
}

// 获取队列详情
async function getQueueDetail() {
	if (conversation.value?.status !== XBCCS.CONVERSATION_STATUS.QUEUEING) return
	const res = await XBCCS.getQueue(conversation.value?.conversationId)
	Object.assign(queue, res)
	await nextTick()
	scrollToBottom()
}

// 监听收到消息
async function onReceiveMessage(msg) {
	// @ts-ignore 当前会话时更新消息列表
	if (msg.conversationId == state.conversationId) {
		// 更新消息状态
		msg.status = XBCCS.MESSAGE_STATUS.SENT
		
		// 判断当前消息是否已经存在列表
		const index = messageList.value.findIndex(message => message.id == msg?.tempId)
		if(index >= 0){
			messageList.value.splice(index, 1, msg)
		}else{
			messageList.value.push(msg)
		}
		
		await nextTick()
		scrollToBottom()
	}
}

// 监听排队会话已接入
function onConversationAccessed() {
	getConversationDetail()
}

// 监听会话结束
function onConversationEnd(conversationIds = []){
	if (conversationIds.includes(conversation.value?.conversationId)){
		// 重新获取会话详情
		getConversationDetail()

		// 显示评价弹窗
		if (config.value?.isComment) {
			commentRef.value?.open()
		}
	}
}

onPageScroll(({ scrollTop }) => {
	currentScrollTop.value = scrollTop
	if(status.value == 'no-more') return
	if(!scrollTop) getList()
	status.value = scrollTop ? 'more' : 'loading'
})

onLoad(async query => {
	state.conversationId = query?.id || ''
	await getConfig()
	await getList()
	getConversationDetail()
	
	XBCCS.on(XBCCS.EVENT.CONVERSATION_END, onConversationEnd)
	XBCCS.on(XBCCS.EVENT.MESSAGE_RECEIVED, onReceiveMessage)
	XBCCS.on(XBCCS.EVENT.CONVERSATION_ACCESSED, onConversationAccessed)
})

onUnload(() => {
	XBCCS.off(XBCCS.EVENT.CONVERSATION_END, onConversationEnd)
	XBCCS.off(XBCCS.EVENT.MESSAGE_RECEIVED, onReceiveMessage)
	XBCCS.off(XBCCS.EVENT.CONVERSATION_ACCESSED, onConversationAccessed)
})
</script>

<style lang="scss" scoped>
.message-list {
	min-height: 100vh;
	background-color: #f5f5f5;
	padding-bottom: env(safe-area-inset-bottom);
	padding-bottom: constant(safe-area-inset-bottom);

	.message-item {
		margin-bottom: 20rpx;
	}
}

.xbc-editor-placeholder {
	height: 92px;
	// transition: height 0.3s ease;
	background-color: #f5f5f5;
}
</style>